package cn.com.surker.sale.service.impl;

import cn.com.surker.common.Code;
import cn.com.surker.database.JDBCTemplateCache;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.sale.*;
import cn.com.surker.enums.system.DataBaseEnum;
import cn.com.surker.enums.system.OrgInfoEnum;
import cn.com.surker.enums.system.PriceTaxEnum;
import cn.com.surker.sale.dao.*;
import cn.com.surker.sale.entity.*;
import cn.com.surker.sale.service.SaleContractBaseService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.*;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.system.entity.SysMessageRecord;
import cn.com.surker.system.entity.SysOrigin;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.OrderNoUtil;
import cn.com.surker.util.StringUtils;
import cn.com.surker.vo.sale.SaleContractVo;
import cn.com.surker.wechat.WechatOaGroupApi;
import cn.com.surker.wechat.WechatSurkerGroupApi;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
 * @Author lucky
 * @create 2024年07月10 10:56
 * @desc
 */
@Slf4j
public abstract class SaleContractBaseServiceImpl extends ServiceImpl<SaleContractDao, SaleContract> implements SaleContractBaseService {

    @Resource
    protected SaleContractDao saleContractDao;
    @Resource
    protected DataSourceInfoDao dsDao;
    @Resource
    protected SysOriginDao sysOriginDao;
    @Resource
    protected SaleClientOrgDao saleClientOrgDao;
    @Resource
    protected SaleClientDao saleClientDao;
    @Resource
    protected ConStatusRecordDao conStatusRecordDao;
    @Resource
    protected SaleManRecordDao saleManRecordDao;
    @Resource
    private SysUserPositionDao userPositionDao;
    @Resource
    private SysUserDao userDao;
    @Resource
    private SysMessageRecordDao sysMessageRecordDao;
    @Resource
    private SaleBillPaymentDao saleBillPaymentDao;
    /**
     * 分页查询
     * @param searchVal
     * @param workStatus 供应状态(2:已授权1:待授权3:终止)
     * @param quality 性质(1:正式2:待签合同,3:零星)
     * @param contractCategory 合同类型1:商砼，2：砂浆，3：水稳层，4：全轻混凝土，5：预制件合同)
     * @param projectCategory 工程类型(0:其他，1：地产类，2：厂房类，3：市政基础建设类)
     * @param billType 结算类型(0:月结，1：先款后货，2：垫资)
     * @param advanceType 垫资类型(-1:不垫资0:垫资方量，1：垫资金额，2：垫资天数)
     * @param workNature 供应性质(0：销售:1：内部代加工、2：外包代加工)
     * @param startTime
     * @param endTime
     * @param offset
     * @param limit
     * @return
     */
    public IPage findPage(String searchVal, Long orgId, Integer workStatus, Integer quality, Integer contractCategory,
                   Integer projectCategory, Integer billType, Integer advanceType, Integer workNature,
                   Integer status, String startTime, String endTime, String sales, Integer offset, Integer limit) {
        PageHelper.offsetPage(offset, limit);
        QueryWrapper<SaleContract> query = new QueryWrapper<>();
        if (StringUtils.isNull(status))
            status = 0;
        if (!StringUtils.isNull(sales))
			query.eq("a.sales", sales);
//			query.and(e -> {
//				e.eq("sales", sales).or().eq("reckoner", sales);
//			});
        if (!StringUtils.isNull(status))
			query.eq("a.status", status);
        if (!StringUtils.isNull(workStatus))
			query.eq("a.work_status", workStatus);
        if (!StringUtils.isNull(quality))
			query.eq("a.quality", quality);
        if (!StringUtils.isNull(orgId))
			query.eq("a.org_id", orgId);
        if (!StringUtils.isNull(contractCategory))
			query.eq("a.contract_category", contractCategory);
        if (!StringUtils.isNull(projectCategory))
			query.eq("a.project_category", projectCategory);
        if (!StringUtils.isNull(billType))
			query.eq("a.bill_type", billType);
        if (!StringUtils.isNull(advanceType))
			query.eq("a.advance_type", advanceType);
        if (!StringUtils.isNull(workNature))
			query.eq("a.work_nature", workNature);
        if (!StringUtils.isNull(startTime))
			query.ge("a.sign_date", startTime);
        if (!StringUtils.isNull(endTime))
			query.lt("a.sign_date", endTime);
        if (!StringUtils.isNull(searchVal)) {
			query.and(orderWrapper -> orderWrapper.like("a.name", searchVal).or()
				.like("a.code", searchVal).or().like("a.build", searchVal)
				.or().like("a.bill_area", searchVal).or().like("a.foreman", searchVal)
				.or().like("a.terms", searchVal).or().like("a.technical", searchVal)
				.or().like("a.ticket_origin", searchVal).or().like("a.sales", searchVal)
				.or().like("a.link_man", searchVal).or().like("a.remark", searchVal)
				.or().inSql("a.client_id", "select id from sale_client where status = 0 and full_name like '%" + searchVal + "%'"));
        }

		query.orderByDesc("a.sign_date");

		Page<SaleContractVo> iPage = saleContractDao.selectListV1(new Page<>((offset + limit) / limit, limit), query);
		/**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    /**
     * 分页查询合同与客户信息
     * @param contract
     * @param offset
     * @param limit
     * @return
     */
    public IPage findVoPage(SaleContract contract, Integer offset, Integer limit) {
        PageHelper.offsetPage(offset, limit);
        QueryWrapper<SaleContract> query = new QueryWrapper<>();
        if (StringUtils.isNull(contract.getStatus()))
            contract.setStatus(0);
        if (!StringUtils.isNull(contract.getOrgId()))
            query.eq("a.org_id", contract.getOrgId());
        if (!StringUtils.isNull(contract.getSales()))
            query.eq("a.sales", contract.getSales());
//			query.and(e -> {
//				e.eq("sales", sales).or().eq("reckoner", sales);
//			});
        if (!StringUtils.isNull(contract.getConIds())) {
            String[] ids = contract.getConIds().split(",");
            if (ids != null && ids.length > 0) {
                query.in("a.id", ids);
            }
        }
        if (!StringUtils.isNull(contract.getNotConIds())) {
            String[] ids = contract.getNotConIds().split(",");
            if (ids != null && ids.length > 0) {
                String conIds = "";
                query.notIn("a.id", ids);
            }
        }

        if (!StringUtils.isNull(contract.getStatus()))
            query.eq("a.status", contract.getStatus());
        if (!StringUtils.isNull(contract.getSearchVal())) {
            String searchVal = StringUtils.convertString(contract.getSearchVal());
            query.and(orderWrapper -> orderWrapper.like("a.name", searchVal).or()
                    .like("a.code", searchVal).or().like("a.build", searchVal)
                    .or().like("a.bill_area", searchVal).or().like("a.foreman", searchVal)
                    .or().like("a.terms", searchVal).or().like("a.technical", searchVal)
                    .or().like("a.ticket_origin", searchVal).or().like("a.sales", searchVal)
                    .or().like("a.link_man", searchVal).or().like("a.remark", searchVal)
                    .or().inSql("a.client_id", "select id from sale_client where status = 0 and full_name like '%" + searchVal + "%'"));
        }

        query.orderByDesc("a.sign_date");

        IPage<SaleContractVo> iPage = saleContractDao.selectListV1(new Page<>((offset + limit) /limit, limit), query);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    /**
     * 根据公司查询销售人员
     * @param orgId
     * @return
     */
    public List<Map<String, Object>> loadSales(Long orgId) {
        if (StringUtils.isNull(orgId))
            return null;
        String time = DateUtil.convertString(DateUtil.convertBeforeMonthDate(new Date(), 12));
        List<Map<String, Object>> list = saleContractDao.findSales(orgId, time);
        if (list == null || list.size() == 0)
            return null;
        return list;
    }
    /**
     * 查询所有合同
     * @param saleContract
     * @return
     */
    public List<SaleContract> findAll(SaleContract saleContract) {
        QueryWrapper<SaleContract> query = new QueryWrapper<>();
        if (saleContract != null) {
            if (!StringUtils.isNull(saleContract.getClientId()))
                query.eq("client_id", saleContract.getClientId());
            if (!StringUtils.isNull(saleContract.getCode()))
                query.like("code", saleContract.getCode());
            if (!StringUtils.isNull(saleContract.getOrgId()))
                query.eq("org_id", saleContract.getOrgId());
            if (!StringUtils.isNull(saleContract.getProjectCategory()))
                query.eq("project_category", saleContract.getProjectCategory());
            if (!StringUtils.isNull(saleContract.getContractCategory()))
                query.eq("contract_category", saleContract.getContractCategory());
            if (!StringUtils.isNull(saleContract.getQuality()))
                query.eq("quality", saleContract.getQuality());
            if (!StringUtils.isNull(saleContract.getIsDisplay()))
                query.eq("is_display", saleContract.getIsDisplay());
			if (!StringUtils.isNull(saleContract.getSales())) {
				String sales = saleContract.getSales();
				query.and(e -> {
					e.eq("sales", sales).or().eq("reckoner", sales);
				});
			}
            if (!StringUtils.isNull(saleContract.getPriceType()))
                query.eq("price_type", saleContract.getPriceType());
			if (saleContract.getErpid() != null) {
				query.eq("erpid", saleContract.getErpid());
			}
			if (saleContract.getWorkStatus() != null) {
				query.eq("work_status", saleContract.getWorkStatus());
			}
        }
        query.eq("status", 0);
        query.lambda().orderByDesc(SaleContract::getCreateTime);
        List<SaleContract> list = saleContractDao.selectList(query);
        return list;
    }

    /**
     * 查询所有合同
     * @param saleContract
     * @return
     */
    public List<SaleContractVo> findAllV1(SaleContract saleContract) {
        if (StringUtils.isNull(saleContract.getStatus()))
            saleContract.setStatus(0);
        return saleContractDao.findSelectContract(saleContract);
    }
    /**
     * 保存合同
     * @param contract
     * @return 返回值如未带erpid或返回未空，则插入失败
     */
    public RestResultDto saveContract(SaleContract contract) {
        if (StringUtils.isNull(contract.getName()))
            return RestResultDto.complete(Code.CONTRACT_NAME_EMPTY.getCode());
        if (StringUtils.isNull(contract.getClientId()))
            return RestResultDto.complete(Code.CLIENT_NAME_EMPTY.getCode());
        if (StringUtils.isNull(contract.getStere()) || contract.getStere() < 0)
            return RestResultDto.complete(Code.CONTRACT_STERE_EMPTY.getCode());
        if (StringUtils.isNull(contract.getBuild()))
            return RestResultDto.complete(Code.BUILD_EMPTY.getCode());
        if (StringUtils.isNull(contract.getClientId()))
            return RestResultDto.complete(Code.SALE_CLIENT_ERROR.getCode());
        if (StringUtils.isNull(contract.getDistance()))
            contract.setDistance(0.0);
        Date nowDate = new Date();
        String contractName = contract.getName().replaceAll("（", "(").replaceAll("）", ")")
                .replaceAll(" ", "").replaceAll("【", "[").replaceAll("】", "]")
                .replaceAll("，", ",").replaceAll("。", ".").replaceAll("\\s+", "");
        contract.setName(contractName);
        if (!StringUtils.isNull(contract.getBuild())) {
            String build = contract.getBuild().replaceAll("（", "(").replaceAll("）", ")")
                    .replaceAll(" ", "").replaceAll("【", "[").replaceAll("】", "]")
                    .replaceAll("，", ",").replaceAll("。", ".").replaceAll("\\s+", "");
            contract.setBuild(build);
        }
        Integer total = saleContractDao.findExistName(contractName, contract.getOrgId(), contract.getClientId());
        if (total > 0)
            return RestResultDto.fail("同一客户,同一类型的工程名称不能重复存在");

        if (StringUtils.isNull(contract.getWorkNature()))
            contract.setWorkNature(ContractWorkNatureEnum.XS.getCode());//合同性质
        if (StringUtils.isNull(contract.getPriceType()))
            contract.setPriceType(ContractPriceTypeEnum.HTJ.getCode());//合同造价类型
        if (StringUtils.isNull(contract.getQuality()))
            contract.setQuality(ContractQualityEnum.LSHT.getCode());//1正式合同，2：临时合同
        if (StringUtils.isNull(contract.getIsWork())) //是否限供
            contract.setIsWork(ContractIsWorkEnum.NO.getCode());
        if (StringUtils.isNull(contract.getIsSupplied())) //是否甲供
            contract.setIsSupplied(ContractIsSuppliedEnum.YES.getCode());
        if (StringUtils.isNull(contract.getContractCategory())) //合同类型
            contract.setContractCategory(ContractCategoryEnum.ST.getCode());
        if (StringUtils.isNull(contract.getProjectCategory())) //工程类型
            contract.setProjectCategory(ContractProjectCategoryEnum.QT.getCode());
        if (StringUtils.isNull(contract.getPaymentCycle())) //默认回款周期
            contract.setPaymentCycle(10);
        if (StringUtils.isNull(contract.getStrategy())) //默认回款周期
            contract.setStrategy(0);
        if (StringUtils.isNull(contract.getSignDate())) //
            contract.setSignDate(DateUtil.convertString(nowDate, "yyyy-MM-dd"));
        if (StringUtils.isNull(contract.getWorkNature()))
            contract.setPriceType(ContractWorkNatureEnum.XS.getCode());//合同性质
        if (!StringUtils.isNull(contract.getPhone()))
            contract.setPhone(contract.getPhone().replaceAll(" ", "").replaceAll("，", ","));
        if (contract.getPriceType().intValue() == ContractPriceTypeEnum.HTJ.getCode().intValue())
            contract.setBillArea("");
        contract.setIsDisplay(0);
        contract.setSales(contract.getSales());//销售人员
        contract.setSumStere(contract.getStere());//总方量
        if (contract.getOrgId().intValue() == OrgInfoEnum.JIU_XING.getId().intValue() || contract.getOrgId().intValue() == OrgInfoEnum.WU_YANG.getId().intValue()
                || contract.getOrgId().intValue() == OrgInfoEnum.ZHENG_JIA.getId().intValue() || contract.getOrgId().intValue() == OrgInfoEnum.DING_HAO.getId().intValue())
            contract.setWorkStatus(ContractWorkStatusEnum.YSQ.getCode());
        else
            contract.setWorkStatus(ContractWorkStatusEnum.DSQ.getCode());
        contract.setOrgId(contract.getOrgId());
        contract.setStatus(0);
        contract.setCreateTime(nowDate);

        SysOrigin origin = sysOriginDao.selectById(contract.getOrgId());
        if (origin == null || origin.getStatus() == 1)
            return RestResultDto.fail(Code.UN_ORIGIN_INFO.getCode());
        if (StringUtils.isNull(contract.getReceiptUnit()))
            contract.setReceiptUnit(origin.getFullName());//小票抬头
        Integer code = saleContractDao.insert(contract);
        if (code < 1)
            return RestResultDto.complete(Code.SAVE_CONTRACT_ERROR.getCode());
        String contractCode = OrderNoUtil.getSaleContractNo(contract.getId(), contract.getQuality(), contract.getWorkNature(), origin.getOriginName());
        contract.setCode(contractCode);
        DataSourceInfo ds = dsDao.queryDSByOriginId(contract.getOrgId());
        if (ds == null || ds.getStatus() == 1)
            return RestResultDto.fail(Code.STATION_ERROR.getCode());
        if (ds.getType() == 1) {
            /**获取数据库联系信息**/
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            Integer reportId = 1;
            String reportSql = "select top 1 * from Sys_ReportTitle_T " +
                    "where IsValid = 1 and titlename = '" + origin.getFullName() + "' order by id desc";
            List<Map<String, Object>> reportList = jdbcTemplate.queryForList(reportSql);
            if (reportList != null && reportList.size() > 0) {
                reportId = StringUtils.convertInteger(reportList.get(0).get("ID"));
            }
            Integer property = 1;
            if (contract.getQuality().intValue() == ContractQualityEnum.LSHT.getCode()
                    || contract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
                property = 2;
                if (contract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
                    if (contract.getOrgId().intValue() == OrgInfoEnum.CHI_XU.getId() || contract.getOrgId().intValue() == OrgInfoEnum.BO_JIU.getId()
                            ||contract.getOrgId().intValue() == OrgInfoEnum.YA_BO.getId() || contract.getOrgId().intValue() == OrgInfoEnum.YA_BO_XIN_CHANG.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.SAI_HUA.getId() || contract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE_ER_ZHAN.getId() || contract.getOrgId().intValue() == OrgInfoEnum.SHENG_TONG.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.ZHONG_GUAN.getId() || contract.getOrgId().intValue() == OrgInfoEnum.ZHEN_YUAN.getId()) {
                        contract.setStere(0.0);
                        contract.setSumStere(0.0);
                    }
                }
            }

            if (!StringUtils.isNull(contract.getBillType()) && contract.getBillType().intValue() == ContractBillTypeEnum.XKHH.getCode().intValue()) {
                if (contract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
                    if (contract.getOrgId().intValue() == OrgInfoEnum.CHI_XU.getId() || contract.getOrgId().intValue() == OrgInfoEnum.BO_JIU.getId()
                            ||contract.getOrgId().intValue() == OrgInfoEnum.YA_BO.getId() || contract.getOrgId().intValue() == OrgInfoEnum.YA_BO_XIN_CHANG.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.SAI_HUA.getId() || contract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE_ER_ZHAN.getId() || contract.getOrgId().intValue() == OrgInfoEnum.SHENG_TONG.getId()
                            || contract.getOrgId().intValue() == OrgInfoEnum.ZHONG_GUAN.getId() || contract.getOrgId().intValue() == OrgInfoEnum.ZHEN_YUAN.getId()) {
                        contract.setStere(0.0);
                        contract.setSumStere(0.0);
                    }
                }
            }
            if (ContractWorkNatureEnum.DJG.getCode().intValue() == contract.getWorkNature().intValue()) {
                property = 3;
            }
            StringBuffer addSql = new StringBuffer();
            addSql.append("insert into Market_Contract_T (Sys_Dept_ID,SignDept,u_name,u_code,clientId,status,property,contractStere,");
            addSql.append("addStere,SumStere,AmountLimit,StereLimit,salesman,signDate,confirm,tabulationPerson,TabulationDate,address,");
            addSql.append("LoadDistance,DevelopmentUnits,remarks,CreatorID,CreationTime,ReviseID,ReviseTime,isValid,sys_reportData_ID,");
            addSql.append("sys_reportTitle_ID, dtype, stere) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");

            String nowTime = DateUtil.convertString(new Date(), "yyyy-MM-dd HH:mm:ss");
            Object[] params = {1, 1, contract.getName(), contractCode, contract.getClientErpId(), 1, property,
                    contract.getStere(), 0.0, contract.getStere(), 0, 0, contract.getSales(), contract.getSignDate(), 1,
                    contract.getCreator(), nowTime, contract.getAddress(), contract.getDistance(),
                    contract.getBuild(), contract.getRemark(), 1, nowTime, 1, nowTime, 1, reportId, reportId,
                    contract.getContractCategory(), contract.getStere()};

            log.info("saveContract:新建合同SQL:{},参数:{}", addSql.toString(), params);
            KeyHolder keyHolder = new GeneratedKeyHolder();
            StringBuffer finalAddSql = addSql;
            Object[] finalParams = params;
            jdbcTemplate.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                    PreparedStatement ps = connection.prepareStatement(finalAddSql.toString(), new String[]{"ID"});
                    for (int i = 0; i < finalParams.length; i++) {
                        ps.setObject(i + 1, finalParams[i]);
                    }
                    return ps;
                }
            }, keyHolder);
            Long taskId = keyHolder.getKey().longValue();
            if (taskId < 1)
                return RestResultDto.fail(Code.SAVE_CONTRACT_ERROR.getCode());
            /**最小方量**/
            Double minStere = 2.0;
            addSql = new StringBuffer("INSERT INTO ContractProject (Market_Contract_ID,U_Name,DevelopmentUnits,Site_Contacter,");
            addSql.append("Site_Contacter_PN,Address,LoadDistance,Remarks,CreatorID,CreationTime,ReviseID,ReviseTime,");
            addSql.append("IsValid,MinSettleStere) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");

            params = new Object[]{taskId, contract.getName(), contract.getBuild(), "", "", contract.getAddress(),
                    contract.getDistance(), contract.getRemark(), 1, nowTime, 1, nowTime, 1, minStere};

            log.info("添加合同项目SQL:{}", addSql);
            code = jdbcTemplate.update(addSql.toString(), params);
            if (code < 1)
                return RestResultDto.fail(Code.SAVE_CONTRACT_ERROR.getCode());

            contract.setErpid(taskId);
        }

        code = saleContractDao.updateById(contract);
        if (code < 1)
            return RestResultDto.complete(Code.SAVE_CONTRACT_ERROR.getCode());
        try {
            SaleManRecord record = new SaleManRecord(contract.getOrgId(), contract.getId(), contract.getName(),
                    contract.getSales(), DateUtil.convertDate(contract.getSignDate(), "yyyy-MM-dd"), 0, "", contract.getCreator(), nowDate);
            saleManRecordDao.insert(record);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResultDto.success(contract);
        }

        return RestResultDto.success(contract);
    }

    /**
     * 修改合同 除workStatus contractCategory不能修改，其他属性均可改变
     * @param contract
     * @return
     */
    public RestResultDto updateContract(SaleContract contract) {
        if (StringUtils.isNull(contract.getId()))
            return RestResultDto.complete(Code.ERROR_DATA.getCode());
        if (StringUtils.isNull(contract.getName()))
            return RestResultDto.complete(Code.CONTRACT_NAME_EMPTY.getCode());
        if (StringUtils.isNull(contract.getClientId()))
            return RestResultDto.complete(Code.CLIENT_NAME_EMPTY.getCode());
        if (StringUtils.isNull(contract.getStere()) || contract.getStere() < 0)
            return RestResultDto.complete(Code.CONTRACT_STERE_EMPTY.getCode());
        if (StringUtils.isNull(contract.getBuild()))
            return RestResultDto.complete(Code.BUILD_EMPTY.getCode());
        if (StringUtils.isNull(contract.getClientId()))
            return RestResultDto.complete(Code.SALE_CLIENT_ERROR.getCode());
        if (StringUtils.isNull(contract.getDistance()))
            contract.setDistance(0.0);
        if (!StringUtils.isNull(contract.getStere()) && !StringUtils.isNull(contract.getAddStere()))
            contract.setSumStere(StringUtils.addDouble(contract.getStere(), contract.getAddStere()));

        Date nowDate = new Date();
        SaleContract saleContract = saleContractDao.selectById(contract.getId());
        if (!StringUtils.isNull(contract.getName()) && !contract.getName().equals(saleContract.getName())) {
            String contractName = contract.getName().replaceAll("（", "(").replaceAll("）", ")")
                    .replaceAll(" ", "").replaceAll("【", "[").replaceAll("】", "]")
                    .replaceAll("，", ",").replaceAll("。", ".").replaceAll("\\s+", "");
            contract.setName(contractName);
            Integer total = saleContractDao.findExistName(contractName, saleContract.getOrgId(), contract.getClientId());
            if (total > 0)
                return RestResultDto.fail("同一客户,同一类型的工程名称不能重复存在");
        }
        if (!StringUtils.isNull(contract.getBuild()) && !contract.getBuild().equals(saleContract.getBuild())) {
            String build = contract.getBuild().replaceAll("（", "(").replaceAll("）", ")")
                    .replaceAll(" ", "").replaceAll("【", "[").replaceAll("】", "]")
                    .replaceAll("，", ",").replaceAll("。", ".").replaceAll("\\s+", "");
            contract.setBuild(build);
        }

        contract.setPhone(contract.getPhone().replaceAll(" ", "").replaceAll("，", ","));
        contract.setUpdateTime(nowDate);
//        contract.setUpdator(contract.getUpdator());
        Integer code = saleContractDao.updateById(contract);
        String orgName = "";
        if (code > 0) {
            if (!StringUtils.isNull(saleContract.getErpid())
                    && saleContract.getErpid() > 1) {
                Integer property = 1;
                if (contract.getQuality().intValue() == ContractQualityEnum.LSHT.getCode()
                        || contract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
                    property = 2;
//                    if (saleContract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
//                        if (saleContract.getOrgId().intValue() == OrgInfoEnum.CHI_XU.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.BO_JIU.getId()
//                        ||saleContract.getOrgId().intValue() == OrgInfoEnum.YA_BO.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.YA_BO_XIN_CHANG.getId()
//                        || saleContract.getOrgId().intValue() == OrgInfoEnum.SAI_HUA.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE.getId()
//                        || saleContract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE_ER_ZHAN.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.SHENG_TONG.getId()
//                        || saleContract.getOrgId().intValue() == OrgInfoEnum.ZHONG_GUAN.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.ZHEN_YUAN.getId()) {
//                            contract.setStere(0.0);
//                            contract.setSumStere(0.0);
//                        }
//                    }
                }
//                if (!StringUtils.isNull(contract.getBillType()) && contract.getBillType().intValue() == ContractBillTypeEnum.XKHH.getCode().intValue()) {
//                    if (saleContract.getQuality().intValue() == ContractQualityEnum.LXHT.getCode()) {
//                        if (saleContract.getOrgId().intValue() == OrgInfoEnum.CHI_XU.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.BO_JIU.getId()
//                                ||saleContract.getOrgId().intValue() == OrgInfoEnum.YA_BO.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.YA_BO_XIN_CHANG.getId()
//                                || saleContract.getOrgId().intValue() == OrgInfoEnum.SAI_HUA.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE.getId()
//                                || saleContract.getOrgId().intValue() == OrgInfoEnum.XIN_YUE_ER_ZHAN.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.SHENG_TONG.getId()
//                                || saleContract.getOrgId().intValue() == OrgInfoEnum.ZHONG_GUAN.getId() || saleContract.getOrgId().intValue() == OrgInfoEnum.ZHEN_YUAN.getId()) {
//                            contract.setStere(0.0);
//                            contract.setSumStere(0.0);
//                        }
//                    }
//                }
                DataSourceInfo ds = dsDao.queryDSByOriginId(saleContract.getOrgId());
                orgName = ds.getName();
                if (ds != null && ds.getStatus() == 0 && ds.getType() == 1) {
                    Long clientErpId = null;
                    if (!StringUtils.isNull(contract.getClientErpId())) {
                        clientErpId = contract.getClientErpId();
                    } else {
                        SaleClientOrg clientOrg = saleClientOrgDao.findByOrg(contract.getClientId(), contract.getOrgId(), 0);
                        if (clientOrg != null)
                            clientErpId = clientOrg.getErpId();
                    }
                    /**获取数据库联系信息**/
                    JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                    String sql = "update Market_Contract_T set u_name = '" + contract.getName() + "', DevelopmentUnits = '"
                            + contract.getBuild() + "',salesman='" + contract.getSales() + "',ReviseID= 1,ReviseTime='"
                            + DateUtil.convertString(nowDate) + "',property=" + property + ",LoadDistance= " + contract.getDistance() + ",SumStere=" + contract.getSumStere() + " ";
                    if (!StringUtils.isNull(saleContract.getReceiptUnit()) && !StringUtils.isNull(contract.getReceiptUnit())
                            && !saleContract.getReceiptUnit().equals(contract.getReceiptUnit())) {
                        Integer reportId = 1;
                        String reportSql = "select top 1 * from Sys_ReportTitle_T " +
                                "where IsValid = 1 and titlename = '" + contract.getReceiptUnit() + "' order by id desc";
                        List<Map<String, Object>> reportList = jdbcTemplate.queryForList(reportSql);
                        if (reportList != null && reportList.size() > 0) {
                            reportId = StringUtils.convertInteger(reportList.get(0).get("ID"));
                            sql += ",sys_reportData_ID=" +reportId + ",sys_reportTitle_ID =" + reportId;
                        }
                    }
                    if (!StringUtils.isNull(clientErpId))
                        sql += ",clientId=" +clientErpId;
                    if (!StringUtils.isNull(saleContract.getErpid())) {
                        sql += " where id = " + saleContract.getErpid();
                    } else if (!StringUtils.isNull(saleContract.getCode())) {
                        sql += " where U_code = '" + code + "'";
                    }
                    if (!StringUtils.isNull(saleContract.getErpid())) {
                        String updateSql = "update contractproject set U_Name = '" + contract.getName() + "',DevelopmentUnits='" + contract.getBuild()
                                + "',LoadDistance= " + contract.getDistance() + " where Market_Contract_ID =" + saleContract.getErpid();
                        jdbcTemplate.update(updateSql);
                    }
                    log.info("updateClient:修改合同信息SQL:{}", sql.toString());
                    Integer resultCode = jdbcTemplate.update(sql.toString());
                    log.info("updateClient: 返回结果:{}", resultCode);
                }
            }

            try{
                SaleClient client = saleClientDao.selectById(contract.getClientId());
                String clientName = client.getFullName();
                if (contract.getClientId().intValue() != saleContract.getClientId().intValue()) {
                    SaleClient oldClient = saleClientDao.selectById(saleContract.getClientId());
                    clientName = "客户:" + oldClient.getFullName() +  " -> " + clientName;
                }
                updateSendMessage(contract, saleContract, clientName, orgName, contract.getUpdator());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return RestResultDto.success(contract);
        }
        return RestResultDto.fail(Code.SAVE_CONTRACT_ERROR.getCode());
    }

    /**
     * 修改合同供应状态
     * @param workStatus 供应状态(2:已授权1:待授权3:终止)
     * @param contractId
     * @param creator
     * @return 次接口需验证权限，除信控专员与管理员，其他人员不得行直接操作
     */
	public Integer updateWorkStatus(Integer workStatus, Long contractId, String creator) {
        if (StringUtils.isAllParamNull(contractId, workStatus))
            return Code.PARAM_EMPTY.getCode();
        SaleContract saleContract = saleContractDao.selectById(contractId);
        if (saleContract == null)
            return Code.ERROR_DATA.getCode();
        Date nowDate = new Date();
        saleContract.setWorkStatus(workStatus);
        saleContract.setUpdator("" + creator);
        saleContract.setUpdateTime(nowDate);
        Integer code = saleContractDao.updateById(saleContract);
        if (code > 0) {
            ConStatusRecord conStatusRecord = new ConStatusRecord(saleContract.getOrgId(), saleContract.getId(),
                    ConStatusRecordEnum.USER.getCode(), workStatus, creator + "操作变更", creator + "", nowDate);
            conStatusRecordDao.insert(conStatusRecord);
            if (StringUtils.isAllParamNull(saleContract.getOrgId(), saleContract.getErpid())
                    || saleContract.getErpid() < 1)
                return 0;
            DataSourceInfo ds = dsDao.queryDSByOriginId(saleContract.getOrgId());
            if (ds == null || ds.getStatus() == 1 || ds.getType() == 0)
                return 0;
            /**获取数据库联系信息**/
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            StringBuffer sql = new StringBuffer();
            sql.append("update Market_Contract_T set ReviseTime = '" + DateUtil.convertString(nowDate) + "', status = ").append(workStatus);
//            if (!StringUtils.isNull(creator)) {
//                sql.append(" ,ReviseID=" + creator);
//            }
            if (!StringUtils.isNull(saleContract.getErpid())) {
                sql.append(" where id = ").append(saleContract.getErpid());
            } else if (!StringUtils.isNull(saleContract.getCode())) {
                sql.append(" where U_code = '").append(code).append("'");
            }
            log.info("updateClient:修改合同信息SQL:{}", sql.toString());
            Integer resultCode = jdbcTemplate.update(sql.toString());
            if (resultCode > 0)
                return 0;
            log.info("updateClient: 返回结果:{}", resultCode);
        }
        return -1;
    }

	public Integer updateWorkStatus2(Integer workStatus, Integer useType, Long contractId, String creator, String recordRemark) {
		if (StringUtils.isAllParamNull(contractId, workStatus))
			return Code.PARAM_EMPTY.getCode();
		SaleContract saleContract = saleContractDao.selectById(contractId);
		if (saleContract == null)
			return Code.ERROR_DATA.getCode();
		Date nowDate = new Date();
		saleContract.setWorkStatus(workStatus);
		saleContract.setUpdator("" + creator);
		saleContract.setUpdateTime(nowDate);
		Integer code = saleContractDao.updateById(saleContract);
		if (code > 0) {
			ConStatusRecord conStatusRecord = new ConStatusRecord(saleContract.getOrgId(), saleContract.getId(),
				useType, workStatus, recordRemark, creator + "", nowDate);
			conStatusRecordDao.insert(conStatusRecord);
			if (StringUtils.isAllParamNull(saleContract.getOrgId(), saleContract.getErpid())
				|| saleContract.getErpid() < 1)
				return 0;
			DataSourceInfo ds = dsDao.queryDSByOriginId(saleContract.getOrgId());
			if (ds == null || ds.getStatus() == 1 || ds.getType() == 0)
				return 0;
			/**获取数据库联系信息**/
			JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
			StringBuffer sql = new StringBuffer();
			sql.append("update Market_Contract_T set ReviseTime = '" + DateUtil.convertString(nowDate) + "', status = ").append(workStatus);
//			if (!StringUtils.isNull(creator)) {
//				sql.append(" ,ReviseID=" + creator);
//			}
			if (!StringUtils.isNull(saleContract.getErpid())) {
				sql.append(" where id = ").append(saleContract.getErpid());
			} else if (!StringUtils.isNull(saleContract.getCode())) {
				sql.append(" where U_code = '").append(code).append("'");
			}
			log.info("updateClient:修改合同信息SQL:{}", sql.toString());
			Integer resultCode = jdbcTemplate.update(sql.toString());
			if (resultCode > 0)
				return 0;
			log.info("updateClient: 返回结果:{}", resultCode);
		}
		return -1;
	}

    /**
     * 分页查询关停记录
     * @param orgId
     * @param conId
     * @param searchVal
     * @param sales
     * @param startTime
     * @param endTime
     * @param offset
     * @param limit
     * @return
     */
    public Map<String, Object> findWorkStatusRecordPage(Long orgId, Long conId,String searchVal, String sales, String startTime,
                                                 String endTime, Integer offset, Integer limit) {
        if (StringUtils.isNull(orgId))
            orgId = null;
        if (StringUtils.isNull(conId))
            conId = null;
        if (StringUtils.isNull(searchVal))
            searchVal = null;
        if (StringUtils.isNull(sales))
            sales = null;
        if (StringUtils.isNull(startTime))
            startTime = null;
        if (StringUtils.isNull(endTime))
            endTime = null;
        Integer total = conStatusRecordDao.findRecordTotal(orgId, conId, searchVal, sales, startTime, endTime);
        List<Map<String, Object>> list = conStatusRecordDao.findRecordPage(orgId, conId, searchVal, sales, startTime, endTime, offset, limit);
        if (list == null || list.size() == 0)
            return null;
        Map<String, Object> map = new HashMap<>();
        map.put("total", total);
        map.put("data", list);
        return map;
    }

    /**
     * 物理删除
     * @param status
     * @param contractId
     * @param creator
     * @return
     */
    public Integer updateStatus(Integer status, Long contractId, Long creator) {
        if (StringUtils.isAllParamNull(contractId, status))
            return Code.PARAM_EMPTY.getCode();
        SaleContract saleContract = saleContractDao.selectById(contractId);
        if (saleContract == null)
            return Code.ERROR_DATA.getCode();
        Date nowDate = new Date();
        saleContract.setStatus(status);
        saleContract.setUpdator("" + creator);
        saleContract.setUpdateTime(nowDate);
        Integer code = saleContractDao.updateById(saleContract);
        if (code > 0) {
            if (StringUtils.isAllParamNull(saleContract.getOrgId(), saleContract.getErpid())
                    || saleContract.getErpid() < 1)
                return 0;
            DataSourceInfo ds = dsDao.queryDSByOriginId(saleContract.getOrgId());
            if (ds == null || ds.getStatus() == 1 || ds.getType() == 0)
                return 0;
            Integer isValid = 1;
            if (status == 1)
                isValid = 0;
            /**获取数据库联系信息**/
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            StringBuffer sql = new StringBuffer();
            sql.append("update Market_Contract_T set ReviseTime = '" + DateUtil.convertString(nowDate) + "', IsValid = ").append(isValid);
            if (!StringUtils.isNull(creator)) {
                sql.append(" ,ReviseID=" + creator);
            }
            if (!StringUtils.isNull(saleContract.getErpid())) {
                sql.append(" where id = ").append(saleContract.getErpid());
            } else if (!StringUtils.isNull(saleContract.getCode())) {
                sql.append(" where U_code = '").append(code).append("'");
            }
            log.info("updateClient:修改合同信息SQL:{}", sql.toString());
            Integer resultCode = jdbcTemplate.update(sql.toString());
            if (resultCode > 0) {
                if (!StringUtils.isNull(saleContract.getErpid())) {
                    String sql1 = "update ContractProject set IsValid = " + isValid + "  where Market_Contract_id = " + saleContract.getErpid();
                    jdbcTemplate.update(sql1);
                }
                return 0;
            }
            log.info("updateClient: 返回结果:{}", resultCode);
        }
        return -1;
    }

	@Override
	public SaleContract findByErpId(Long orgId, Long erpId) {
		/*QueryWrapper<SaleContract> qw = new QueryWrapper<>();
		qw.eq("org_id", orgId);
		qw.eq("erpid", erpId);
		List<SaleContract> saleContractList = saleContractDao.selectList(qw);
		if (saleContractList == null || saleContractList.isEmpty()) {
			return null;
		}
		SaleContract contract = saleContractList.get(0);*/
		SaleContract contract = saleContractDao.findByErpId(orgId, erpId);
		return contract;
	}

	@Override
	public SaleContract findByErpName(Long orgId, String erpConName) {
		SaleContract contract = saleContractDao.findByErpName(orgId, erpConName);
		return contract;
	}

	/**
     * 查询合同完成总量
     * @param contractId
     * @return
     */
    public Map<String, Object> queryContractRate(Long contractId) {
        Map<String, Object> map = new HashMap<>();
        map.put("sumStere", 0);
        map.put("sendStere", 0);
        map.put("completeRate", 0);
        if (StringUtils.isNull(contractId))
            return map;

        SaleContract contract = saleContractDao.selectById(contractId);
        if (contract == null || StringUtils.isNull(contract.getErpid()))
            return map;
        DataSourceInfo ds = dsDao.queryDSByOriginId(contract.getOrgId());
        if (ds == null) {
            ds = dsDao.queryDSByOriginIdV1(contract.getOrgId(), DataBaseEnum.MYSQL.getCode());
            if (ds == null)
                return map;
        }
        if (ds.getType() == 1) {
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            String sql = "select (ISNULL(SUM(ContractStere),0) + ISNULL(SUM(AddStere),0)) sumStere from Market_Contract_T where IsValid = 1 and id = ? ";
            Object[] obj = {contract.getErpid()};

            /**合同总方量**/
            Double sumStere = StringUtils.convertDouble(jdbcTemplate.queryForList(sql, obj).get(0).get("sumStere"));
            sql = "select ISNULL(SUM(a3.VerifyStere),0) sendStere from Market_Contract_T a1 left join Market_Indent_T a2 " +
                    " on a1.ID = a2.Market_Contract_ID left join Production_Invoice_T a3 on a2.ID = a3.Market_Indent_ID " +
                    " where a1.IsValid = 1 and a1.id = ?  and a2.IsValid = 1 and a3.IsValid = 1 \n" +
                    "and a3.status = 2 and a3.InvoiceType = 1";

            /**发货方量**/
            Double sendStere = StringUtils.convertDouble(jdbcTemplate.queryForList(sql, obj).get(0).get("sendStere"));

//        sumStere = 100.0;
//        sendStere = 46.3;
            if (sumStere == 0)
                sumStere = 0.01;
            Double completeRate = MathUtils.divide(sendStere, sumStere);
            completeRate = MathUtils.multiply(completeRate, 100d);
            map.put("sumStere", sumStere);
            map.put("sendStere", sendStere);
            map.put("completeRate", completeRate);
        } else if (ds.getType() == 0) {
            SaleBillPayment billPayment = saleBillPaymentDao.findTotalContract(contractId, null);
            Double sumStere = StringUtils.formatDouble(contract.getSumStere(), 1);
            Double sendStere = 0.0;
            if (billPayment != null)
                sendStere = billPayment.getProStere();
            if (sumStere == 0)
                sumStere = 0.01;
            Double completeRate = MathUtils.divide(sendStere, sumStere);
            completeRate = MathUtils.multiply(completeRate, 100d);
            map.put("sumStere", sumStere);
            map.put("sendStere", sendStere);
            map.put("completeRate", completeRate);
        }

        return map;
    }

	@Override
	public SaleContractVo queryById(Long conId) {
		if (conId == null) {
			return null;
		}
		SaleContractVo contract = saleContractDao.selectById(conId);
		return contract;
	}


	public List<Map<String, Object>> masterList(Long orgId) {
		if (orgId == null) {
			return null;
		}
		List<Map<String, Object>> mList = saleContractDao.masterList(orgId);
		return mList;
	}

	@Override
	public List<SaleContract> slaveList(Long orgId, Long conId, Long slaveId) {
		if (conId == null) {
			return null;
		}
		if (StringUtils.isNull(slaveId))
            slaveId = null;

		QueryWrapper<SaleContract> qw = new QueryWrapper<>();
		qw.eq("status", StateEnum.ENABLED.getCode());
		qw.eq("batch_id", conId);
		List<SaleContract> saleContractList = saleContractDao.slaveList(orgId, conId, slaveId);
		return saleContractList;
	}

    /**
     * 查询发票抬头
     * @return
     */
//    @Cacheable(cacheNames = "queryDatasourceInfo")
    public List<SysOrigin> findReportUnit() {
        QueryWrapper<SysOrigin> query = new QueryWrapper<>();
        query.eq("status", 0);
        query.eq("type", 2);
        query.like("full_name", "公司");
        query.orderByAsc("sortby");
        List<SysOrigin> dsList = sysOriginDao.selectList(query);

        return dsList;
    }

	public List<SaleContract> queryConList(Long conId, Long orgId, Long clientId, String name, String code, Integer quality, Integer workStatus, Integer workNature, Integer contractCategory, String sales, String linkMan, String foreman) {
		QueryWrapper<SaleContract> qw = new QueryWrapper<>();
		if (conId != null) {
			qw.eq("a.id", conId);
		}
		if (orgId != null) {
			qw.eq("a.org_id", orgId);
		}
		if (clientId != null) {
			qw.eq("a.client_id", clientId);
		}
		if (StringUtils.isNotBlank(name)) {
			qw.like("a.name", name);
		}
		if (StringUtils.isNotBlank(code)) {
			qw.like("a.code", code);
		}
		if (quality != null) {
			qw.like("a.quality", quality);
		}
		if (workStatus != null) {
			qw.eq("a.work_status", workStatus);
		}
		if (workNature != null) {
			qw.eq("a.work_nature", workNature);
		}
		if (contractCategory != null) {
			qw.eq("a.contract_category", contractCategory);
		}
		if (StringUtils.isNotBlank(sales)) {
			qw.and(e -> {
				e.eq("sales", sales).or().eq("reckoner", sales);
			});
		}
		if (StringUtils.isNotBlank(linkMan)) {
			qw.like("a.linkMan", linkMan);
		}
		if (StringUtils.isNotBlank(foreman)) {
			qw.like("a.foreman", foreman);
		}
		qw.eq("a.status", StateEnum.ENABLED.getCode());
		List<SaleContract> contractList = saleContractDao.selectListV1(qw);
		return contractList;
	}

	public SaleContract queryCon(Long conId, Long orgId, Long clientId, String name, String code, Integer quality, Integer workStatus, Integer workNature, Integer contractCategory, String sales, String linkMan, String foreman) {
		List<SaleContract> contractList = queryConList(conId, orgId, clientId, name, code, quality, workStatus, workNature, contractCategory, sales, linkMan, foreman);
		if (contractList == null || contractList.isEmpty()) {
			return null;
		}
		SaleContract contract = contractList.get(0);
		return contract;
	}

    /**
     * 查询不限供合同
     * @param orgId
     * @return
     */
    public List<SaleContract> findWorkByOrg(Long orgId) {

        return saleContractDao.findWorkByOrg(orgId);
    }

    /**
     * 变更合同消息推送
     * @param newContract
     * @param oldContract
     * @param clientName
     */
    private void updateSendMessage(SaleContract newContract, SaleContract oldContract, String clientName,
                                   String orgName, String updater) {
        if (updater.equals("万强") || updater.equals("罗涛") || updater.equals("马杰") || updater.equals("谭世杰"))
            return;
        Map<Integer, Object> contractCategoryMap = new HashMap<>();//合同类型
        Map<Integer, Object> projectCategoryMap = new HashMap<>();//工程类型
        Map<Integer, Object> priceTypeMap = new HashMap<>();//合同造价类型
        Map<Integer, Object> qualityMap = new HashMap<>();//合同类型
        Map<Integer, Object> workNatureMap = new HashMap<>();//供应性质
        Map<Integer, Object> workStatusMap = new HashMap<>();//供应状态
        Map<Integer, Object> billTypeMap = new HashMap<>();//结算类型
        Map<Integer, Object> advanceTypeMap = new HashMap<>();//垫资方式
        Map<Integer, Object> adjustPriceTypeMap = new HashMap<>();//造价信息调整方式
        Map<Integer, Object> priceTaxMap = new HashMap<>();//造价信息是否含税
        Map<Integer, Object> businessQualityMap = new HashMap<>();
        Map<Integer, Object> isWorkMap = new HashMap<>();
        Date nowDate = new Date();
        for (int i = 0; i < ContractIsWorkEnum.values().length; i++) {
            isWorkMap.put(ContractIsWorkEnum.values()[i].getCode(), ContractIsWorkEnum.values()[i].getDescription());
        }
        for (int i = 0; i < BusinessQualityEnum.values().length; i++) {
            businessQualityMap.put(BusinessQualityEnum.values()[i].getCode(), BusinessQualityEnum.values()[i].getDescription());
        }
        for (int i = 0; i < PriceTaxEnum.values().length; i++) {
            priceTaxMap.put(PriceTaxEnum.values()[i].getCode(), PriceTaxEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractWorkStatusEnum.values().length; i++) {
            workStatusMap.put(ContractWorkStatusEnum.values()[i].getCode(), ContractWorkStatusEnum.values()[i].getDescription());
        }
        for (int i = 0; i < AdjustPriceTypeEnum.values().length; i++) {
            adjustPriceTypeMap.put(AdjustPriceTypeEnum.values()[i].getCode(), AdjustPriceTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractCategoryEnum.values().length; i++) {
            contractCategoryMap.put(ContractCategoryEnum.values()[i].getCode(), ContractCategoryEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractProjectCategoryEnum.values().length; i++) {
            projectCategoryMap.put(ContractProjectCategoryEnum.values()[i].getCode(), ContractProjectCategoryEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractPriceTypeEnum.values().length; i++) {
            priceTypeMap.put(ContractPriceTypeEnum.values()[i].getCode(), ContractPriceTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractQualityEnum.values().length; i++) {
            qualityMap.put(ContractQualityEnum.values()[i].getCode(), ContractQualityEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractWorkNatureEnum.values().length; i++) {
            workNatureMap.put(ContractWorkNatureEnum.values()[i].getCode(), ContractWorkNatureEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractBillTypeEnum.values().length; i++) {
            billTypeMap.put(ContractBillTypeEnum.values()[i].getCode(), ContractBillTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < ContractAdvanceTypeEnum.values().length; i++) {
            advanceTypeMap.put(ContractAdvanceTypeEnum.values()[i].getCode(), ContractAdvanceTypeEnum.values()[i].getDescription());
        }
        String message = "【销售工程变更通知】" + orgName + "\n";
        message += "合同编号:" + oldContract.getCode() + "\n";
        if (!StringUtils.isNull(newContract.getName())) {//工程名称
            String name = "";
            if (!StringUtils.isNull(oldContract.getName()) && !oldContract.getName().equals(newContract.getName()))
                name = "工程:" + oldContract.getName() + " -> " + newContract.getName();
            else
                name = "工程:" + newContract.getName();
            message += name + "\n";
        }
        message += "客户:" + clientName + "\n";
        if (!StringUtils.isNull(newContract.getBuild())) {//工地联系人
            String name = "";
            if (!StringUtils.isNull(oldContract.getBuild()) && !oldContract.getBuild().equals(newContract.getBuild())) {
                name = "施工单位:" + oldContract.getBuild() + " -> " + newContract.getBuild();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getContractCategory())) {//合同类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getContractCategory()) && !oldContract.getContractCategory().equals(newContract.getContractCategory()))
                name = "合同类型:" + contractCategoryMap.get(oldContract.getContractCategory()) + " -> " + contractCategoryMap.get(newContract.getContractCategory());
            else
                name = "合同类型:" + contractCategoryMap.get(newContract.getContractCategory());
            message += name + "\n";
        }
        if (!StringUtils.isNull(newContract.getTicketOrigin())) {//合同类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getTicketOrigin()) && !oldContract.getTicketOrigin().equals(newContract.getTicketOrigin())) {
                name = "开票单位:" + oldContract.getTicketOrigin() + " -> " + newContract.getTicketOrigin();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getWorkStatus())) {//供应性质
            String name = "";
            if (!StringUtils.isNull(oldContract.getWorkStatus()) && !oldContract.getWorkStatus().equals(newContract.getWorkStatus()))
                name = "供应状态:" + workStatusMap.get(oldContract.getWorkStatus()) + " -> " + workStatusMap.get(newContract.getWorkStatus());
            else
                name = "供应状态:" + workStatusMap.get(newContract.getWorkStatus());
            message += name + "\n";
        }
        if (!StringUtils.isNull(newContract.getQuality())) {//性质
            String name = "";
            if (!StringUtils.isNull(oldContract.getQuality()) && !oldContract.getQuality().equals(newContract.getQuality())) {
                name = "性质:" + qualityMap.get(oldContract.getQuality()) + " -> " + qualityMap.get(newContract.getQuality());
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getAdjustPriceType())) {//信息价调整类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getAdjustPriceType()) && !oldContract.getAdjustPriceType().equals(newContract.getAdjustPriceType())) {
                name = "信息价调整类型:" + adjustPriceTypeMap.get(oldContract.getAdjustPriceType()) + " -> " + adjustPriceTypeMap.get(newContract.getAdjustPriceType());
                message += name + "\n";
            }
        }
        message += "签订日期:" + newContract.getSignDate().substring(0,10) + "\n";
        message += "总方量:" + newContract.getSumStere() + "m³\n";
        message += "业务员:" + newContract.getSales() + "\n";
        if (!StringUtils.isNull(newContract.getBillArea())) {//信息价地区
            String name = "信息价地区:" + newContract.getBillArea();
            message += name + "\n";
        }
        if (!StringUtils.isNull(newContract.getDistance())) {//运距
            String name = "";
            if (!StringUtils.isNull(oldContract.getDistance())
                    && !oldContract.getDistance().equals(newContract.getDistance())) {
                name = "运距:" + oldContract.getDistance() + "km -> " + newContract.getDistance() + "km";
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getPriceType())) {//结算日期
            String name = "";
            if (!StringUtils.isNull(oldContract.getPriceType()) && !oldContract.getPriceType().equals(newContract.getPriceType())){
                name = "是否开票:" + (oldContract.getPriceType() == 1 ? "合同价" : "信息价") + " -> " + (newContract.getPriceType() == 0 ? "合同价" : "信息价");
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getIsTicket())) {//结算日期
            String name = "";
            if (!StringUtils.isNull(oldContract.getIsTicket()) && !oldContract.getIsTicket().equals(newContract.getIsTicket())){
                name = "是否开票:" + (oldContract.getIsTicket() == 0 ? "不开票" : "开票") + " -> " + (newContract.getIsTicket() == 0 ? "不开票" : "开票");
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getIsPriceTax())) {//结算日期
            String name = "";
            if (!StringUtils.isNull(oldContract.getIsPriceTax()) && !oldContract.getIsPriceTax().equals(newContract.getIsPriceTax())){
                name = "单价是否含税:" + (oldContract.getIsPriceTax() == 0 ? "不含税" : "含税") + " -> " + (newContract.getIsPriceTax() == 0 ? "不含税" : "含税");
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getBillDay())) {//结算日期
            String name = "";
            if (!StringUtils.isNull(oldContract.getBillDay())
                    && !oldContract.getBillDay().equals(newContract.getBillDay())) {
                name = "结算日期:" + oldContract.getBillDay() + "日 -> " + newContract.getBillDay() + "日";
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getPaymentCycle())) {//回款间隔时间
            String name = "";
            if (!StringUtils.isNull(oldContract.getPaymentCycle())
                    && !oldContract.getPaymentCycle().equals(newContract.getPaymentCycle())) {
                name = "回款间隔时间:" + oldContract.getPaymentCycle() + "天 -> " + newContract.getPaymentCycle() + "天";
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getBillType())) {//结算类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getBillType())
                    && !oldContract.getBillType().equals(newContract.getBillType())) {
                name = "结算类型:" + billTypeMap.get(oldContract.getBillType()) + " -> " + billTypeMap.get(newContract.getBillType());
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getPriceComposeType())) {//单价生成类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getPriceComposeType()) && !oldContract.getPriceComposeType().equals(newContract.getPriceComposeType())){
                name = "单价生成类型:" + (oldContract.getPriceComposeType() == 0 ? "组合类型" : "固定类型") + " -> " + (newContract.getPriceComposeType() == 0 ? "组合类型" : "固定类型");
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getRate())) {//结算比例
            String name = "";
            if (!StringUtils.isNull(oldContract.getRate()) && !oldContract.getRate().equals(newContract.getRate())) {
                name = "结算比例:" + oldContract.getBillRate() + "% -> " + newContract.getBillRate() + "%";
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getAdvanceType())) {//结算类型
            String name = "";
            if (!StringUtils.isNull(oldContract.getAdvanceType()) && !oldContract.getAdvanceType().equals(newContract.getAdvanceType())) {
                name = "垫资类型:" + advanceTypeMap.get(oldContract.getAdvanceType()) + " -> " + advanceTypeMap.get(newContract.getAdvanceType());
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getAdvanceContent())) {//垫资内容
            String name = "";
            String unit = "";
            String newUnit = "";
            if (newContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZTS.getCode().intValue())
                newUnit = "天";
            else if (newContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZJE.getCode().intValue())
                newUnit = "元";
            else if (newContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZFL.getCode().intValue())
                newUnit = "m³";
            if (oldContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZTS.getCode().intValue())
                unit = "天";
            else if (oldContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZJE.getCode().intValue())
                unit = "元";
            else if (oldContract.getAdvanceType().intValue() == ContractAdvanceTypeEnum.DZFL.getCode().intValue())
                unit = "m³";
            if (!StringUtils.isNull(oldContract.getAdvanceContent()) && !oldContract.getAdvanceContent().equals(newContract.getAdvanceContent())) {
                name = "垫资内容:" + oldContract.getAdvanceContent() + unit + " -> " + newContract.getAdvanceContent() + newUnit;
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getIsWork())) {//是否限供
            String name = "";
            String unit = "";
            String newUnit = "";
            if (newContract.getIsWork().intValue() == ContractIsWorkEnum.JE.getCode().intValue())
                newUnit = "元";
            else if (newContract.getIsWork().intValue() == ContractIsWorkEnum.FL.getCode().intValue())
                newUnit = "m³";
            if (oldContract.getIsWork().intValue() == ContractIsWorkEnum.JE.getCode().intValue())
                unit = "元";
            else if (oldContract.getIsWork().intValue() == ContractIsWorkEnum.FL.getCode().intValue())
                unit = "m³";
            if (!StringUtils.isNull(oldContract.getIsWork()) && !oldContract.getIsWork().equals(newContract.getIsWork())) {
                name = "限供内容:" + oldContract.getWorkContent() + unit + " -> " + newContract.getWorkContent() + newUnit;
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getAcceptance())) {//结算签字人
            String name = "";
            if (!StringUtils.isNull(oldContract.getAcceptance()) && !oldContract.getAcceptance().equals(newContract.getAcceptance())) {
                name = "结算签字人:" + oldContract.getAcceptance() + " -> " + newContract.getAcceptance();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getForeman())) {//工地联系人
            String name = "";
            if (!StringUtils.isNull(oldContract.getForeman()) && !oldContract.getForeman().equals(newContract.getForeman())) {
                name = "工长:" + oldContract.getForeman() + " -> " + newContract.getForeman();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getReckoner())) {//结算人
            String name = "";
            if (!StringUtils.isNull(oldContract.getReckoner()) && !oldContract.getReckoner().equals(newContract.getReckoner())) {
                name = "结算人:" + oldContract.getReckoner() + " -> " + newContract.getReckoner();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getLinkMan())) {//工地联系人
            String name = "";
            if (!StringUtils.isNull(oldContract.getLinkMan()) && !oldContract.getLinkMan().equals(newContract.getLinkMan())) {
                name = "工地联系人:" + oldContract.getLinkMan() + " -> " + newContract.getLinkMan();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getPhone())) {//工地联系电话
            String name = "";
            if (!StringUtils.isNull(oldContract.getPhone()) && !oldContract.getPhone().equals(newContract.getPhone())) {
                name = "工地联系电话:" + oldContract.getPhone() + " -> " + newContract.getPhone();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getAddress())) {//工地地址
            String name = "";
            if (!StringUtils.isNull(oldContract.getAddress()) && !oldContract.getAddress().equals(newContract.getAddress())){
                name = "工地地址:" + oldContract.getAddress() + " -> " + newContract.getAddress();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getTerms())) {//付款条件
            String name = "";
            if (!StringUtils.isNull(oldContract.getTerms()) && !oldContract.getTerms().equals(newContract.getTerms())){
                name = "付款条件:" + newContract.getAddress();
                message += name + "\n";
            }
        }
        if (!StringUtils.isNull(newContract.getConditions())) {//违约内容
            String name = "";
            if (!StringUtils.isNull(oldContract.getConditions()) && !oldContract.getConditions().equals(newContract.getConditions())){
                name = "违约内容:" + newContract.getConditions();
                message += name + "\n";
            }
        }
        message += "操作人员:" + updater;
        String touser = "lucky|1lt1556|";
        String toname = "万强|罗涛|";
        List<Map<String, Object>> list = userPositionDao.hasGeneralManager(oldContract.getOrgId(), "销售内业", "信控专员");
        if (!StringUtils.isNull(oldContract.getSales())) {
            SysUser user = userDao.queryByName(oldContract.getSales());
            if (user != null && toname.indexOf(user.getName()) == -1) {
                toname += user.getName() + "|";
                touser += user.getUsername() + "|";
            }
        }
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Map<String, Object> temp = list.get(i);
                String name = StringUtils.convertString(temp.get("name"));
                if (!StringUtils.isNull(name) && toname.indexOf(name) == -1) {
                    toname += temp.get("name") + "|";
                    touser += temp.get("username") + "|";
                }
            }
        }

        toname = toname.substring(0, toname.length() - 1);
        touser = touser.substring(0, touser.length() - 1);
        SysMessageRecord record = new SysMessageRecord(touser, toname, "", WechatOaGroupApi.corpID, "", newContract.getOrgId(),
                "", 1, 1, "合同变更推送", "",
                message, "", 1, 0, "", "", nowDate);
        sysMessageRecordDao.insert(record);
        WechatOaGroupApi.sendTextMessage(WechatOaGroupApi.corpID, WechatOaGroupApi.corpSecret,
                WechatOaGroupApi.agentId, touser, message);

    }

    @Override
    public List<SaleContract> findWorkByOrg(Long orgId, Integer category) {
        QueryWrapper<SaleContract> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SaleContract::getOrgId, orgId);
        queryWrapper.lambda().eq(SaleContract::getContractCategory, category);
        return list(queryWrapper);
    }
}
